package cn.chiship.framework.upms.biz.base.controller;


import cn.chiship.framework.common.constants.CommonCacheConstants;
import cn.chiship.sdk.cache.service.RedisService;
import cn.chiship.sdk.core.annotation.NoParamsSign;
import cn.chiship.sdk.core.base.BaseResult;
import cn.chiship.sdk.core.base.constants.CacheConstants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * @author lijian
 */
@RestController
@RequestMapping("/captcha")
@Api(tags = "图形验证码")
public class CaptchaController {
    @Resource
    private RedisService redisService;

    @ApiOperation(value = "获取验证码图片")
    @GetMapping("getCaptchaCode")
    @NoParamsSign
    public void getCaptchaCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        outputCaptcha(request, response);
    }

    @ApiOperation(value = "获取验证码文本")
    @GetMapping("getCaptchaCodeText")
    @NoParamsSign
    public ResponseEntity<BaseResult> getCaptchaCodeText(HttpServletRequest request) {
        String randomString = getRandomString().toUpperCase();
        request.getSession(true).setAttribute("KAPTCHA_SESSION_KEY", randomString);
        redisService.hset(CommonCacheConstants.buildKey(CacheConstants.REDIS_CAPTCHA_PREFIX), randomString, randomString, 3600);
        return new ResponseEntity<>(BaseResult.ok(randomString), HttpStatus.OK);
    }

    private static final char[] CHARS = {
            '1', '2', '3', '4', '5', '6', '7', '8', '9',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
    };

    private static Random random = new Random();
    private static final int CHARS_LENGTH = 4;
    private static final int RECT_NUMBER = 100;

    private static String getRandomString() {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < CHARS_LENGTH; i++) {
            builder.append(CHARS[random.nextInt(CHARS.length)]);
        }
        return builder.toString();
    }

    private static Color getRandomColor() {
        return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
    }

    private static Color getReverseColor() {
        return new Color(255, 255, 255);
    }

    public void outputCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {

        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/jpeg");

        String randomString = getRandomString().toUpperCase();
        request.getSession(true).setAttribute("KAPTCHA_SESSION_KEY", randomString);
        redisService.hset(CommonCacheConstants.buildKey(CacheConstants.REDIS_CAPTCHA_PREFIX), randomString, randomString, 3600);
        int width = 100;
        int height = 35;
        Color color = getRandomColor();
        Color reverse = getReverseColor();

        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = bi.createGraphics();
        g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16));
        g.setColor(reverse);
        g.fillRect(0, 0, width, height);
        g.setColor(color);
        g.drawString(randomString, 18, 20);
        for (int i = 0, n = random.nextInt(RECT_NUMBER); i < n; i++) {
            g.drawRect(random.nextInt(width), random.nextInt(height), 1, 1);
        }

        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(bi, "png", out);
        out.flush();
    }

}